package com.btpj.hospital_server.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.btpj.hospital_server.dto.*;
import com.btpj.hospital_server.dto.param.VisitPlanParam;
import com.btpj.hospital_server.service.*;
import com.github.pagehelper.PageHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Api(tags = "出诊计划接口")
@RestController
@RequestMapping("/visitPlan")
public class VisitPlanController {

    @Resource
    private VisitPlanService visitPlanService;

    @Resource
    private HospitalInfoService hospitalInfoService;

    @Resource
    private HospitalSpecialService hospitalSpecialService;

    @Resource
    private HospitalOutpatientService hospitalOutpatientService;

    @Resource
    private HospitalClinicService hospitalClinicService;

    @Resource
    private HospitalDoctorService hospitalDoctorService;

    @ApiOperation("添加出诊计划")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "hospitalId", value = "医院编号", required = true, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "specialId", value = "专科编号", required = true, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "outpatientId", value = "门诊编号", required = true, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "clinicId", value = "诊室编号", required = true, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "doctorId", value = "医生编号", required = true, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "time", value = "时间段 1：上午，2：下午", required = true, dataType = "Int", paramType = "query"),
            @ApiImplicitParam(name = "day", value = "出诊日期(yyyy-MM-dd HH:mm:ss)", required = true, dataType = "Date", paramType = "query"),
    })
    @PostMapping("/add")
    public CommonResult<Void> addVisitPlan(@Validated VisitPlanParam param) {
        CommonResult<Void> checkResult = checkParamValidate(param, true);
        if (checkResult != null) return checkResult;

        if (visitPlanService.addVisitPlan(param)) {
            return CommonResult.success("添加出诊计划成功");
        }

        return CommonResult.error("服务器出错，添加出诊计划失败");
    }

    @ApiOperation("更新出诊计划")
    @ApiImplicitParam(name = "id", value = "出诊编号", required = true, dataType = "Long", paramType = "path")
    @PutMapping("/update/{id}")
    public CommonResult<Void> addVisitPlan(@PathVariable Long id, @Validated VisitPlanParam param) {
        if (!visitPlanService.exist(id)) {
            return CommonResult.error("不存在当前编号的出诊计划");
        }

        CommonResult<Void> checkResult = checkParamValidate(param, false);
        if (checkResult != null) return checkResult;

        if (visitPlanService.updateVisitPlan(id, param)) {
            return CommonResult.success("更新出诊计划成功");
        }

        return CommonResult.error("服务器出错，更新出诊计划失败");
    }

    @ApiOperation("删除出诊计划")
    @ApiImplicitParam(name = "id", value = "出诊编号", required = true, dataType = "Long", paramType = "path")
    @DeleteMapping("/delete/{id}")
    public CommonResult<Void> deleteVisitPlan(@PathVariable Long id) {
        if (!visitPlanService.exist(id)) {
            return CommonResult.error("不存在当前编号的出诊计划");
        }

        if (visitPlanService.deleteVisitPlan(id)) {
            return CommonResult.success("删除出诊计划成功");
        }

        return CommonResult.error("服务器出错，删除出诊计划失败");
    }

    @ApiOperation("批量删除出诊计划")
    @ApiImplicitParam(name = "ids", value = "出诊编号列表", required = true, dataType = "Long", allowMultiple = true, paramType = "query")
    @DeleteMapping("/deleteBatch")
    public CommonResult<Void> deleteVisitPlan(@RequestParam List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return CommonResult.error("出诊编号列表为空");
        }

        if (visitPlanService.deleteBatch(ids)) {
            return CommonResult.success("批量删除出诊计划成功");
        }

        return CommonResult.error("服务器出错，批量删除出诊计划失败");
    }

    @ApiOperation("分页查询出诊计划列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "hospitalId", value = "医院编号", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "specialId", value = "专科编号", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "outpatientId", value = "门诊编号", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "day", value = "出诊日期(yyyy-MM-dd)", paramType = "query", dataType = "String", required = true),
            @ApiImplicitParam(name = "pageNo", value = "第几页", paramType = "query", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", paramType = "query", dataType = "Integer", required = true),
    })
    @GetMapping("/pageList")
    public CommonResult<CommonPage<VisitPlanDTO>> queryVisitPlan(@RequestParam(required = false) Long hospitalId,
                                                                 @RequestParam(required = false) Long specialId,
                                                                 @RequestParam(required = false) Long outpatientId,
                                                                 @RequestParam String day,
                                                                 @RequestParam Integer pageNo,
                                                                 @RequestParam Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        CommonPage<VisitPlanDTO> commonPage = CommonPage.listPage(visitPlanService.queryList(hospitalId, specialId, outpatientId, null, DateUtil.parse(day)));
        return CommonResult.success(commonPage);
    }

    @ApiOperation(value = "获取医生出诊信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生编号", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "startDateStr", value = "开始日期（yyyy-MM-dd）", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endDateStr", value = "结束日期（yyyy-MM-dd）", required = true, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/getDetailByDoctor")
    public CommonResult<DoctorVisitPlanDTO> searchVisitPlanByDoctor(@RequestParam Long doctorId,
                                                                    @RequestParam String startDateStr,
                                                                    @RequestParam String endDateStr) {

        if (!hospitalDoctorService.existDoctor(doctorId)) {
            return CommonResult.error("不存在，该医生编号！");
        }

        Date startDate = DateUtil.parseDate(startDateStr);
        Date endDate = DateUtil.parseDate(endDateStr);

        if (startDate.getTime() > endDate.getTime()) {
            return CommonResult.error("结束日期不可大于开始日期");
        }

        return CommonResult.success(visitPlanService.getDoctorPlan(doctorId, startDate, endDate));
    }

    @ApiOperation(value = "根据医院编号、医生编号、日期，获取出诊信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "hospitalId", value = "医院编号", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "doctorId", value = "医生编号", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "date", value = "日期（yyyy-MM-dd）", required = true, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/getDetailByHospitalAndDoctorAndDate")
    public CommonResult<List<VisitPlanResiduesDTO>> searchVisitPlanByDoctorAndDate(@RequestParam Long hospitalId,
                                                                                   @RequestParam Long doctorId,
                                                                                   @RequestParam String date) {

        if (!hospitalInfoService.existHospital(hospitalId)) {
            return CommonResult.error("不存在，该医院编号！");
        }

        if (!hospitalDoctorService.existDoctor(doctorId)) {
            return CommonResult.error("不存在，该医生编号！");
        }

        Date time = DateUtil.parseDate(date);

        return CommonResult.success(visitPlanService.getVisitPlanByHospitalAndDoctorAndDate(hospitalId, doctorId, time));
    }

    /**
     * 校验出诊计划参数是否正确
     *
     * @param param VisitPlanParam
     * @return 提示错误信息CommonResult
     */
    private CommonResult<Void> checkParamValidate(VisitPlanParam param, boolean isAdd) {
        Long hospitalId = param.getHospitalId();
        if (isAdd && hospitalId == null) {
            return CommonResult.error("医院编号不可为空");
        }

        if (hospitalId != null && !hospitalInfoService.existHospital(hospitalId)) {
            return CommonResult.error("不存在此医院编号");
        }


        Long specialId = param.getSpecialId();
        if (isAdd && specialId == null) {
            return CommonResult.error("专科编号不可为空");
        }
        if (specialId != null && !hospitalSpecialService.existSpecial(specialId)) {
            return CommonResult.error("不存在此专科编号");
        }

        Long outpatientId = param.getOutpatientId();
        if (isAdd && outpatientId == null) {
            return CommonResult.error("门诊编号不可为空");
        }
        if (outpatientId != null && !hospitalOutpatientService.existOutpatient(outpatientId)) {
            return CommonResult.error("不存在此门诊编号");
        }

        Long clinicId = param.getClinicId();
        if (isAdd && clinicId == null) {
            return CommonResult.error("诊室编号不可为空");
        }
        if (clinicId != null && !hospitalClinicService.existClinic(clinicId)) {
            return CommonResult.error("不存在此诊室编号");
        }

        Long doctorId = param.getDoctorId();
        if (isAdd && doctorId == null) {
            return CommonResult.error("医生编号不可为空");
        }
        if (doctorId != null && !hospitalDoctorService.existDoctor(doctorId)) {
            return CommonResult.error("不存在此医生编号");
        }

        Integer time = param.getTime();
        if (isAdd && time == null) {
            return CommonResult.error("出诊时间段不可为空");
        }

        Date day = param.getDay();
        if (isAdd && day == null) {
            return CommonResult.error("出诊日期不可为空");
        }
        return null;
    }
}
